home *** CD-ROM | disk | FTP | other *** search
Wrap
ddddeeeemmmmaaaannnngggglllleeee((((3333CCCC++++++++)))) ddddeeeemmmmaaaannnngggglllleeee((((3333CCCC++++++++)))) NNNNAAAAMMMMEEEE dem, demangle - demangle C++ external names to a readable format SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS _####_iiii_nnnn_cccc_llll_uuuu_dddd_eeee _<<<<_dddd_eeee_mmmm_...._hhhh_>>>> _cccc_cccc _[[[[_f_l_a_g ..._]]]] _f_i_l_e ... _----_llll_mmmm_aaaa_nnnn_gggg_llll_eeee _[[[[_l_i_b_r_a_r_y ..._]]]] _tttt_yyyy_pppp_eeee_dddd_eeee_ffff _ssss_tttt_rrrr_uuuu_cccc_tttt _DDDD_EEEE_MMMM_AAAA_RRRR_GGGG _DDDD_EEEE_MMMM_AAAA_RRRR_GGGG_;;;; _tttt_yyyy_pppp_eeee_dddd_eeee_ffff _ssss_tttt_rrrr_uuuu_cccc_tttt _DDDD_EEEE_MMMM_CCCC_LLLL _DDDD_EEEE_MMMM_CCCC_LLLL_;;;; _tttt_yyyy_pppp_eeee_dddd_eeee_ffff _ssss_tttt_rrrr_uuuu_cccc_tttt _DDDD_EEEE_MMMM _DDDD_EEEE_MMMM_;;;; _iiii_nnnn_tttt _dddd_eeee_mmmm_aaaa_nnnn_gggg_llll_eeee_((((_cccc_oooo_nnnn_ssss_tttt _cccc_hhhh_aaaa_rrrr _****_iiii_nnnn_,,,, _cccc_hhhh_aaaa_rrrr _****_oooo_uuuu_tttt_))))_;;;; _iiii_nnnn_tttt _dddd_eeee_mmmm_((((_cccc_hhhh_aaaa_rrrr _****_ssss_,,,, _DDDD_EEEE_MMMM _****_pppp_,,,, _cccc_hhhh_aaaa_rrrr _****_bbbb_uuuu_ffff_))))_;;;; _vvvv_oooo_iiii_dddd _dddd_eeee_mmmm______pppp_rrrr_iiii_nnnn_tttt_cccc_llll_((((_DDDD_EEEE_MMMM_CCCC_LLLL _****_pppp_,,,, _cccc_hhhh_aaaa_rrrr _****_bbbb_uuuu_ffff_))))_;;;; _vvvv_oooo_iiii_dddd _dddd_eeee_mmmm______pppp_rrrr_iiii_nnnn_tttt_aaaa_rrrr_gggg_((((_DDDD_EEEE_MMMM_AAAA_RRRR_GGGG _****_pppp_,,,, _cccc_hhhh_aaaa_rrrr _****_bbbb_uuuu_ffff_,,,, _iiii_nnnn_tttt _ffff_))))_;;;; _vvvv_oooo_iiii_dddd _dddd_eeee_mmmm______pppp_rrrr_iiii_nnnn_tttt_aaaa_rrrr_gggg_llll_iiii_ssss_tttt_((((_DDDD_EEEE_MMMM_AAAA_RRRR_GGGG _****_pppp_,,,, _cccc_hhhh_aaaa_rrrr _****_bbbb_uuuu_ffff_,,,, _iiii_nnnn_tttt _ssss_vvvv_))))_;;;; _iiii_nnnn_tttt _dddd_eeee_mmmm______pppp_rrrr_iiii_nnnn_tttt_((((_DDDD_EEEE_MMMM _****_pppp_,,,, _cccc_hhhh_aaaa_rrrr _****_bbbb_uuuu_ffff_))))_;;;; _vvvv_oooo_iiii_dddd _dddd_eeee_mmmm______pppp_rrrr_iiii_nnnn_tttt_ffff_uuuu_nnnn_cccc_((((_DDDD_EEEE_MMMM _****_dddd_pppp_,,,, _cccc_hhhh_aaaa_rrrr _****_bbbb_uuuu_ffff_))))_;;;; DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN _dddd_eeee_mmmm and _dddd_eeee_mmmm_aaaa_nnnn_gggg_llll_eeee are interfaces for user programs to ``demangle'' the mangled external names that C++ produces for functions, class members, etc.. A description of the C++ mangling scheme is provided on page 122 and following of the Annotated C++ Reference Manual. The simplest interface to the library is to call the ddddeeeemmmmaaaannnngggglllleeee(((()))) function, as follows: int ret; char inbuf[1024]; char outbuf[MAXDBUF]; if ((ret = demangle(inbuf, outbuf)) < 0) { /* error! */ } The _dddd_eeee_mmmm_aaaa_nnnn_gggg_llll_eeee_((((_)))) function will return 0 if it successfully demangled the name. If the demangle operation fails, the input string (inbuf) is copied to the output buffer (outbuf). To attain a finer level of control over the demangling operation, call the _dddd_eeee_mmmm_((((_)))) function as follows: PPPPaaaaggggeeee 1111 ddddeeeemmmmaaaannnngggglllleeee((((3333CCCC++++++++)))) ddddeeeemmmmaaaannnngggglllleeee((((3333CCCC++++++++)))) int ret; char inbuf[1024]; DEM d; char sbuf[MAXDBUF]; ret = dem(inbuf, &d, sbuf); where inbuf is the input name, d the data structure that dem() fills up, and sbuf is used as an internal buffer that the demangler uses to allocate this data structure (d will contain pointers into sbuf). Note that the first parameter to dem() is of type char *, not const char *: a call to dem() may alter its input. There is a constant _MMMM_AAAA_XXXX_DDDD_BBBB_UUUU_FFFF defined in dem.h. This is the maximum size of buffer required for an unmangled name's data structure. dem() returns -1 on error, otherwise 0. The include file _<<<<_dddd_eeee_mmmm_...._hhhh_>>>> has comments describing each field in the data structures. The data structures are somewhat complicated by the need to handle nested types and function arguments which themselves are function pointers with their own arguments. To format this data structure in various ways, there are several functions: _dddd_eeee_mmmm______pppp_rrrr_iiii_nnnn_tttt_((((_)))) formats a complete demangled name from the contents of the DEM structure. _dddd_eeee_mmmm______pppp_rrrr_iiii_nnnn_tttt_cccc_llll_((((_)))) formats just a class name. _dddd_eeee_mmmm______pppp_rrrr_iiii_nnnn_tttt_ffff_uuuu_nnnn_cccc_((((_)))) format just a function name. _dddd_eeee_mmmm______pppp_rrrr_iiii_nnnn_tttt_aaaa_rrrr_gggg_((((_)))) formats a single function argument. _dddd_eeee_mmmm______pppp_rrrr_iiii_nnnn_tttt_aaaa_rrrr_gggg_llll_iiii_ssss_tttt_((((_)))) formats a complete function argument list. DDDDIIIIAAAAGGGGNNNNOOOOSSSSTTTTIIIICCCCSSSS _dddd_eeee_mmmm_aaaa_nnnn_gggg_llll_eeee_((((_)))), _dddd_eeee_mmmm_((((_)))) and _dddd_eeee_mmmm______pppp_rrrr_iiii_nnnn_tttt_((((_)))) return 0 if they succeed, and -1 if the input name is not a valid mangled name (or if there are any other error conditions, like passing in invalid arguments). EEEEXXXXAAAAMMMMPPPPLLLLEEEE This particular application reads from standard input and displays the class name for each mangled name read, or "(none)" on errors and C functions/data. #include <stdio.h> #include <dem.h> main() { char sbuf[MAXDBUF]; DEM d; int ret; PPPPaaaaggggeeee 2222 ddddeeeemmmmaaaannnngggglllleeee((((3333CCCC++++++++)))) ddddeeeemmmmaaaannnngggglllleeee((((3333CCCC++++++++)))) char buf[1024]; char buf2[1024]; while (gets(buf) != NULL) { ret = dem(buf, &d, sbuf); if (ret || d.cl == NULL) { printf("%s --> (none)\n", buf); } else { dem_printcl(d.cl, buf2); printf("%s --> %s\n", buf, buf2); } } } TTTTYYYYPPPPEEEENNNNAAAAMMMMEEEESSSS The demangler handles mangled class typenames, whether they are simple, nested, or template classes. For example: A__pt__2_i --> A<int> __Q2_1A1B --> A::B LLLLOOOOCCCCAAAALLLL VVVVAAAARRRRIIIIAAAABBBBLLLLEEEESSSS The demangler also handles local variables of the form: __nnnxxx For example: __2x --> x BBBBUUUUGGGGSSSS AAAANNNNDDDD AAAAMMMMBBBBIIIIGGGGUUUUIIIITTTTIIIIEEEESSSS 1. "signed" and "volatile" encodings are not handled. 2. The encoding for nested classes as mentioned on page 123 of the ARM is handled slightly differently in cfront; there is a "_" after the digit after the "Q". 3. A nested class starting with "Q" sometimes has the length encoded before it; the demangler handles either case. 4. The "Tnn" and "Nnnn" notations mentioned on page 124 are not fully supported. It is assumed that the number of the designated argument is less than or equal to 9. So if you have 11 or more arguments, and you want to repeat argument 10 or greater, the demangler will reject the encoded name. PPPPaaaaggggeeee 3333 ddddeeeemmmmaaaannnngggglllleeee((((3333CCCC++++++++)))) ddddeeeemmmmaaaannnngggglllleeee((((3333CCCC++++++++)))) 5. All literal arguments to templates are assumed to be const. For example, the non-const literal value "37" is encoded as "Ci". 6. Some compilers will add a gratuitous "_" before external names. 7. The grammar allows class names up to 999 characters. This is considered important for handling templates. GGGGRRRRAAAAMMMMMMMMAAAARRRR FFFFOOOORRRR EEEEXXXXTTTTEEEERRRRNNNNAAAALLLL NNNNAAAAMMMMEEEESSSS start --> name ################# COMPLETE NAMES ################# name --> sti | std | ptbl | func | data | vtbl | cname3 | local sti --> "__sti" "__" id std --> "__std" "__" id ptbl --> "__ptbl_vec" "__" id func --> "__op" arg funcpost | id funcpost funcpost --> "__" funcpost2 | "__" cname funcpost2 funcpost2 --> csv "F" arglist csv --> "" | "C" | "S" | "V" data --> id | id "__" cname vtbl --> "__vtbl" "__" cname local --> "__" num regid ################# CLASS NAMES ################# cname --> cname2 | nest nest --> "Q" digit "_" cnamelist cnamelist --> cname2 | cnamelist cname2 cname2 --> cnlen cnid cname3 --> cnid | "__" nest cnlen --> digit | digit digit | digit digit digit cnid --> id | id "__pt__" cnlen "_" arglist ################# ARGUMENT LISTS ################# arglist --> arg | arglist arg arg --> modlist arg2 | "X" modlist arg2 lit modlist --> mod | modlist mod mod --> "" | "U" | "C" | "V" | "S" | "P" | "R" | arr | mptr arr --> "A" num "_" mptr --> "M" cname arg2 --> fund | cname | funcp | repeat1 | repeat2 fund --> "v" | "c" | "s" | "i" | "l" | "f" | "d" | "r" | "e" funcp --> "F" arglist "_" arg repeat1 --> "T" digit | "T" digit digit PPPPaaaaggggeeee 4444 ddddeeeemmmmaaaannnngggglllleeee((((3333CCCC++++++++)))) ddddeeeemmmmaaaannnngggglllleeee((((3333CCCC++++++++)))) repeat2 --> "N" digit digit | "N" digit digit digit lit --> litnum | zero | litmptr | cnlen id | sptr litnum --> "L" digit lnum | "L" digit digit "_" lnum litmptr --> "LM" num "_" litnum "_" cnlen id lnum --> num | "n" num sptr --> cnlen id "__" cname zero --> 0 ################# LOW LEVEL STUFF ################# digit --> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 id --> special | regid special --> "__ct" | "__pp" # etc. regid --> letter | letter restid restid --> letter | digit | restid letter | restid digit letter --> "A"-"Z" | "a" - "z" | "_" num --> digit | num digit PPPPaaaaggggeeee 5555